/**
 * @author Liu Cong
 */
(function(){
const Cc = Components.classes;
const Ci = Components.interfaces;

/**
 * Utility class to walk through a data stream byte by byte with conventional names
 *
 */
FireAMF.BinaryStream = function(dataString){
	if(dataString instanceof Ci.nsIInputStream){
		var stream = dataString;
	} else {
	    var stream = Cc["@mozilla.org/io/string-input-stream;1"]
							.createInstance(Ci.nsIStringInputStream);
	    if ("data" in stream) // Gecko 1.9 or newer
	        stream.data = dataString;
	    else // 1.8 or older
	        stream.setData(dataString, dataString.length);
	}
		
	var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
            createInstance(Ci.nsIBinaryInputStream);
	binaryStream.setInputStream(stream);
	this._stream = binaryStream;
};

FireAMF.BinaryStream.prototype = {
    /**
     * Read the number of bytes in a row for the length supplied.
     *
     * @param  int length
     * @return string
     */
	readBytes: function(length){
		return this._stream.readBytes(length);
	},
	
    /**
     * Reads an unsigned byte
     *
     * @return int Value is in the range of 0 to 255.
     */
	readByte: function(){
		return this._stream.read8();
	},
	
    /**
     * Reads an unsigned 16-bit integer from the data stream.
     *
     * @return int Value is in the range of 0 to 65535
     */
	readInt: function(){
		return this._stream.read16();
	},
	
    /**
     * Reads a UTF-8 string from the data stream
     *
     * @return string A UTF-8 string produced by the byte representation of characters
     */
	readUTF: function(){
		var length = this.readInt();
		return this.readBytes(length);
	},
	
    /**
     * Read a long UTF string
     *
     * @return string
     */
	readLongUTF: function(){
		var length = this.readLong();
		return this.readBytes(length);
	},

    /**
     * Read an unsigned 32bit integer from the data stream
     *
     * @return int
     */
	readLong: function(){
		return this._stream.read32();
	},
	
    /**
     * Read a 16 bit unsigned short.
     *
     * @return double
     */
	readUnsignedShort: function(){
		return this._stream.read16();
	},
	
    /**
     * Reads an IEEE 754 double-precision floating point number from the data stream.
     *
     * @return double Floating point number
     */
	readDouble: function(){
		return this._stream.readDouble();
	}
};

})();
